package ru.urfc.portal.rest;

import java.io.IOException;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import ru.urfc.portal.exceptions.InternalException;
import ru.urfc.portal.managers.DocumentManager;
import ru.urfc.portal.model.documents.AttachedFileList;

@Stateless
@Produces({MediaType.APPLICATION_XML, MediaType.TEXT_XML, MediaType.APPLICATION_JSON})
public class AttachedFilesService {
	
	private FileItemFactory factory = new DiskFileItemFactory();
	private ServletFileUpload fileUpload = new ServletFileUpload(factory);

    private static final String CLIENT_ID = "clientId";  
	private static final String DOCUMENT_ID = "documentId";  
	private static final String FILE_NAME = "fileName";  
	
	@EJB DocumentManager documentManager;
	
	@GET
	public AttachedFileList listFiles(
			@PathParam(CLIENT_ID) Long clientId, @PathParam(DOCUMENT_ID) Long documentId) {
		return new AttachedFileList(documentManager.getAttachedFiles(clientId, documentId)); 
	}
	
	@SuppressWarnings("unchecked")
	@POST
	public String uploadFile(
			@PathParam(CLIENT_ID) Long clientId, @PathParam(DOCUMENT_ID) Long documentId,
			@Context HttpServletRequest request) throws FileUploadException {
		List<FileItem> files = fileUpload.parseRequest(request);
		documentManager.attachFiles(clientId, documentId, files);
		return "ok";
	}
	
	@Path("{" + FILE_NAME + "}")
	public SubService getSubService() {
		return new SubService(); 
	}
	
 	static class ReadAttachedFileException extends InternalException {
 		public ReadAttachedFileException(Throwable cause, String messageTemplate, Object... arguments) {
 			super(cause, messageTemplate, arguments);
 		}
 	}
	
	public class SubService {

		@Produces(MediaType.APPLICATION_OCTET_STREAM)
		@GET
		public String downloadFile(
				@PathParam(CLIENT_ID) Long clientId, @PathParam(DOCUMENT_ID) Long documentId,
				@PathParam(FILE_NAME) String fileName, @Context HttpServletResponse response) {
			try {
				documentManager.getAttachedFileContent(clientId, documentId, fileName, response.getOutputStream());
				return "";
			} catch (IOException e) {
				throw new ReadAttachedFileException(e, "Unable to read file ''{0}''", fileName);
			}
		}
	 
		@DELETE
		public void deleteFile(
				@PathParam(CLIENT_ID) Long clientId, @PathParam(DOCUMENT_ID) Long documentId,
				@PathParam(FILE_NAME) String fileName) {
			documentManager.deleteFile(clientId, documentId, fileName);
		}
		
	}
	
}
